#include <stdio.h>
#include "Date.h"

Date::Date():
year(1970), month(1), day(1) {
}

Date::Date(int _y, int _m, int _d):
year(_y), month(_m), day(_d) {
}

Date::Date(const Date &other){
	day = other.day;
	month = other.month;
	year = other.year;
}

Date& Date::SetYear(int n){
	year = n;
	return *this;
}

Date& Date::SetMonth(int n){
	month = n > 12 || n < 1 ? month : n;
	return *this;
}

Date& Date::SetDay(int n){
	day = n;
	return *this;
}

Date& Date::IncYear(int n){
	year += n;
	return *this;
}

Date& Date::IncMonth(int n){
	month += n;
	while (month > 12){
		month -= 12;
		year += 1;
	}
	while (month < 1){
		month += 12;
		year -= 1;
	}
	return *this;
}

Date& Date::IncDay(int n){
	day += n;
	while (day > DaysInMonth(month)){
		day -= DaysInMonth(month);
		IncMonth(1);
	}
	while (day < 1){
		day += DaysInMonth(month - 1);
		IncMonth(-1);
	}
	return *this;
}

bool Date::IsLeap() const{
	return IsLeap(year);
}

bool Date::IsLeap(int n){
	if (n % 4 == 0 && n % 100 != 0 || n % 400 == 0)
		return true;
	else
		return false;
}

int Date::DaysInMonth(int n) const{
	switch (n){
		case 0: case 1: case 3: case 5: case 7: case 8: case 10: case 12:
			return 31;
			break;
		case 4: case 6: case 9: case 11:
			return 30;
			break;
		case 2:
			if (IsLeap()) 
				return 29;
			else
				return 28;
		default:
			return 0;
	}
}

int Date::DayOfWeek() const{
	int d = day;
	int m = month - 2;
	int y = year % 100;
	int c = year / 100;
	if (m < 1) {
		m += 12;
		y -=1;
	}
	if (y < 0){
		y = 99;
		c -= 1;
	}
	return (d + (13 * m - 1) / 5 + y + y / 4 + c / 4 - 2 * c);
}

void Date::Print() const{
	printf("%d/%d/%d\n", day, month, year);
}

char* Date::NameOfDay() const{
	int flag = DayOfWeek();
	while (flag < 0)
		flag += 7;
	switch (flag % 7){
		case 0: return "Sunday";
			break;
		case 1: return "Monday";
			break;
		case 2: return "Tuesday";
			break;
		case 3: return "Wednesday";
			break;
		case 4: return "Thursday";
			break;
		case 5: return "Friday";
			break;
		case 6: return "Saturday";
			break;
		default: return "";
	}
}